//
//  HHObservableStateObject.swift
//  HHSwiftuiPractice
//
//  Created by YL-Hong on 2023/10/9.
//
/**
 @ObservedObject和@StateObject的区别和用法:
 @ObservedObject用于将一个可观察对象(ObservedObject)注入到一个视图中。常用于在视图间共享数据模型。
 @StateObject用于在一个视图内部管理一个可观察对象的状态。
 
 主要区别是:

 @ObservedObject 属性包装器用于标记类（class）的属性，表示该属性是一个可观察对象，也就是说，当该属性发生变化时，SwiftUI 会自动更新依赖于该属性的视图，@StateObject 属性包装器与 @ObservedObject 类似，都用于跟踪对象的变化，但是有一个重要的区别。@StateObject 用于在 SwiftUI 视图层次结构中创建一个全局唯一的对象，这个对象可以在子视图中共享和访问，而不需要在每个子视图中传递该对象
 @ObservedObject生命周期由父视图管理,@StateObject生命周期由当前视图管理。
 @ObservedObject适合在多个视图间共享数据,@StateObject适合在单个视图内使用。
 
 @StateObject会在视图消失时自动移除生命周期由SwiftUI管理, @ObservedObject需手动移除。

 所以:@StateObject用于单视图状态管理,@ObservedObject用于多视图数据共享。

 */

import SwiftUI

struct FruitModel: Identifiable, Hashable {
    let id: String = UUID().uuidString
    let name: String
    let count: Int
}

class FruitViewModel: ObservableObject {
    @Published var fruits: [FruitModel] = []
    @Published var isLoading: Bool = true
    
    init() {
        getFruits()
    }
    
    //删除
    func delete(indexSet: IndexSet) {
        fruits.remove(atOffsets: indexSet)
    }
    
    //加载数据
    func getFruits() {
        isLoading = true
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
            let appleFruit = FruitModel(name: "Apples", count: 3)
            let orangeFruit = FruitModel(name: "Orange", count: 1)
            let watermelonFruit = FruitModel(name: "Watermelon", count: 1)
            let bananaFruit = FruitModel(name: "Banana", count: 19)
            
            self.fruits.append(appleFruit)
            self.fruits.append(orangeFruit)
            self.fruits.append(watermelonFruit)
            self.fruits.append(bananaFruit)
            self.fruits.append(bananaFruit)
            self.isLoading = false
        })
    }
}


struct HHObservableStateObject: View {
    @StateObject var fruitViewModel: FruitViewModel = FruitViewModel()
    
    var body: some View {
        NavigationView {
                  List {
                      if fruitViewModel.isLoading {
                          ProgressView()
                      }
                      
                      ForEach(fruitViewModel.fruits, id: \.self) { fruit in
                          HStack {
                              Text("\(fruit.count)")
                                  .font(.subheadline)
                              
                              Text(fruit.name)
                                  .font(.subheadline)
                                  .fontWeight(.semibold)
                          }
                          .frame(height: 45)
                      }
                      .onDelete(perform: fruitViewModel.delete(indexSet:))
                  }
                  .listStyle(.grouped)
                  .navigationTitle("Shopping list")
                  .toolbar {
                      ToolbarItem(placement: .navigationBarTrailing, content: {
                          NavigationLink(
                              destination: AnalyzeView(fruitViewModel: fruitViewModel)
                          ) {
                              Image(systemName: "cellularbars")
                          }
                      })
                  }
              }
        
    }
}

struct AnalyzeView: View {
    
    @ObservedObject var fruitViewModel: FruitViewModel

    var body: some View {
        ZStack {
            Color.white.edgesIgnoringSafeArea(.all)
            
            VStack(spacing: 20) {
                
                Text("\(fruitViewModel.fruits.count)")
                    .font(.largeTitle)
                    .fontWeight(.semibold)
                    .underline()
                    .foregroundColor(.white)
                
                Text("Total count")
                    .foregroundColor(.white)
                    .font(.headline)
                    .fontWeight(.semibold)
            }
            .padding(40)
            .background(Color.blue.cornerRadius(10))
        }
    }
}


struct HHObservableStateObject_Previews: PreviewProvider {
    static var previews: some View {
        HHObservableStateObject()
    }
}
